18 research outputs found

    Technical Report: Using Loop Scopes with for-Loops

    Full text link
    Loop scopes have been shown to be a helpful tool in creating sound loop invariant rules which do not require program transformation of the loop body. Here we extend this idea from while-loops to for-loops and also present sound loop unrolling rules for while- and for-loops, which require neither program transformation of the loop body, nor the use of nested modalities. This approach allows for-loops to be treated as first-class citizens -- rather than the usual approach of transforming for-loops into while-loops -- which makes semi-automated proofs easier to follow for the user, who may need to provide help in order to finish the proof

    Abstract Execution: Automatically Proving Infinitely Many Programs

    Get PDF
    Abstract programs contain schematic placeholders representing potentially infinitely many concrete programs. They naturally occur in multiple areas of computer science concerned with correctness: rule-based compilation and optimization, code refactoring and other source-to-source transformations, program synthesis, Correctness-by-Construction, and more. Mechanized correctness arguments about abstract programs are frequently conducted in interactive environments. While this permits expressing arbitrary properties quantifying over programs, substantial effort has to be invested to prove them manually by writing proof scripts. Existing approaches to proving abstract program properties automatically, on the other hand, lack expressiveness. Frequently, they only support placeholders representing all possible instantiations; in some cases, minor refinements are supported. This thesis bridges that gap by presenting Abstract Execution (AE), an automatic reasoning technique for universal behavioral properties of abstract programs. The restriction to universal (no existential quantification) and behavioral (not addressing internal structure) properties excludes certain applications; however, it is the key to automation. Our logic for Abstract Execution uses abstract state changes to represent unknown effects on local variables and the heap, and models abrupt completion by symbolic branching. In this logic, schematic placeholders have names: It is possible to re-use them at several places, representing the same program elements in potentially different contexts. Furthermore, the represented concrete programs can be constrained by an expressive specification language, which is a unique feature of AE. We use the theory of dynamic frames to scale between full abstraction and total precision of frame specifications, and support fine-grained pre- and postconditions for (abrupt) completion. We implemented AE by extending the program verifier KeY. Specifically for relational verification of abstract Java programs, we developed REFINITY, a graphical KeY frontend. We used REFINITY it in our signature application of AE: to model well-known statement-level refactoring techniques and prove their conditional safety. Several yet undocumented behavioral preconditions for safe refactorings originated in this case study, which is one of very few attempts to statically prove behavioral correctness of statement-level refactorings, and the only one to cover them to that extent. AE extends Symbolic Execution (SE) for abstract programs. As a foundational contribution, we propose a general framework for SE based on the semantics of symbolic states. It natively integrates state merging by supporting m-to-n transitions. We define two orthogonal correctness notions, exhaustiveness and precision, and formally prove their relation to program proving and bug detection. Finally, we introduce Modal Trace Logic (MTL), a trace-based logic to represent a variety of different program verification tasks, especially for relational verification. It is a “plug-in” logic which can be integrated on-demand with formal languages that have a trace semantics. The core of MTL is the trace modality, which allows expressing that a specification approximates an implementation after a trace abstraction step. We demonstrate the versatility of this approach by formalizing concrete verification tasks in MTL, ranging from functional verification over program synthesis to program evolution. To reason about MTL problems, we translate them to symbolic traces. We suggest Symbolic Trace Logic (STL), which comes with a sequent calculus to prove symbolic trace inclusions. This requires checking symbolic states for subsumption; to that end, we provide two generally useful notions of symbolic state subsumption. This framework relates as follows to the other parts of this thesis: We use the language of abstract programs to express synthesis and compilation, which connects MTL to AE. Moreover, symbolic states of STL are based on our framework for SE

    Input Invariants

    Get PDF
    Grammar-based fuzzers are highly efficient in producing syntactically valid system inputs. However, as context-free grammars cannot capture semantic input features, generated inputs will often be rejected as semantically invalid by a target program. We propose ISLa, a declarative specification language for context-sensitive properties of structured system inputs based on context-free grammars. With ISLa, it is possible to specify input constraints like "a variable has to be defined before it is used," "the length of the 'file name' block in a TAR file has to equal 100 bytes," or "the number of columns in all CSV rows must be identical." ISLa constraints can be used for parsing or validation ("Does an input meet the expected constraint?") as well as for fuzzing, since we provide both an evaluation and input generation component. ISLa embeds SMT formulas as an island language, leveraging the power of modern solvers like Z3 to solve atomic semantic constraints. On top, it adds universal and existential quantifiers over the structure of derivation trees from a grammar, and structural ("X~occurs before~Y") and semantic ("X~is the checksum of~Y") predicates. ISLa constraints can be specified manually, but also mined from existing input samples. For this, our ISLearn prototype uses a catalog of common patterns (such as the ones above), instantiates these over input elements, and retains those candidates that hold for the inputs observed and whose instantiations are fully accepted by input-processing programs. The resulting constraints can then again be used for fuzzing and parsing. In our evaluation, we show that a few ISLa constraints suffice to produce inputs that are 100% semantically valid while still maintaining input diversity. Furthermore, we confirm that ISLearn mines useful constraints about definition-use relationships and (implications between) the existence of "magic constants", e.g., for programming languages and network packets

    Certified Abstract Cost Analysis

    Get PDF
    A program containing placeholders for unspecified statements or expressions is called an abstract (or schematic) program. Placeholder symbols occur naturally in program transformation rules, as used in refactoring, compilation, optimization, or parallelization. We present a generalization of automated cost analysis that can handle abstract programs and, hence, can analyze the impact on the cost of program transformations. This kind of relational property requires provably precise cost bounds which are not always produced by cost analysis. Therefore, we certify by deductive verification that the inferred abstract cost bounds are correct and sufficiently precise. It is the first approach solving this problem. Both, abstract cost analysis and certification, are based on quantitative abstract execution (QAE) which in turn is a variation of abstract execution, a recently developed symbolic execution technique for abstract programs. To realize QAE the new concept of a cost invariant is introduced. QAE is implemented and runs fully automatically on a benchmark set consisting of representative optimization rules

    Delta-based Verification of Software Product Families

    Get PDF
    The quest for feature- and family-oriented deductive verification of software product lines resulted in several proposals. In this paper we look at delta-oriented modeling of product lines and combine two new ideas: first, we extend HĂ€hnle & Schaefer’s delta-oriented version of Liskov’s substitution principle for behavioral subtyping to work also for overridden behavior in benign cases. For this to succeed, programs need to be in a certain normal form. The required normal form turns out to be achievable in many cases by a set of program transformations, whose correctness is ensured by the recent technique of abstract execution. This is a generalization of symbolic execution that permits reasoning about abstract code elements. It is needed, because code deltas contain partially unknown code contexts in terms of “original” calls. Second, we devise a modular verification procedure for deltas based on abstract execution, representing deltas as abstract programs calling into unknown contexts. The result is a “delta-based” verification approach, where each modification of a method in a code delta is verified in isolation, but which overcomes the strict limitations of behavioral subtyping and works for many practical programs. The latter claim is substantiated with case studies and benchmarks

    Semantic Debugging

    Get PDF
    Why does my program fail? We present a novel and general technique to automatically determine failure causes and conditions, using logical properties over input elements: "The program fails if and only if int(⟹length⟩) > len(⟹payload⟩) holds - that is, the given ⟹length⟩ is larger than the ⟹payload⟩ length." Our AVICENNA prototype uses modern techniques for inferring properties of passing and failing inputs and validating and refining hypotheses by having a constraint solver generate supporting test cases to obtain such diagnoses. As a result, AVICENNA produces crisp and expressive diagnoses even for complex failure conditions, considerably improving over the state of the art with diagnoses close to those of human experts

    Semantic Debugging

    Get PDF
    Why does my program fail? We present a novel and general technique to automatically determine failure causes and conditions, using logical properties over input elements: "The program fails if and only if int(⟹length⟩) > len(⟹payload⟩) holds - that is, the given ⟹length⟩ is larger than the ⟹payload⟩ length." Our AVICENNA prototype uses modern techniques for inferring properties of passing and failing inputs and validating and refining hypotheses by having a constraint solver generate supporting test cases to obtain such diagnoses. As a result, AVICENNA produces crisp and expressive diagnoses even for complex failure conditions, considerably improving over the state of the art with diagnoses close to those of human experts

    Assessing the Coverage of Formal Specifications (Extended Abstract)

    No full text
    Deductive program verification is an intricate and time-consuming task, in spite of significant advances in state-of-the-art program provers. While proving the correctness of programs with respect to existing specifications can already be difficult, it can be even more demanding to come up with sensible specifications for methods and especially for loops. Another issue is related to programs heavily making use of software libraries: Their verification can be considered almost infeasible due to the lack of formal specifications of the libraries. We propose a method for assessing the coverage/strength of formal specifications based on “facts” extracted using heavyweight symbolic execution. We envision that this method can be employed for (1) assisting verification engineers in the incremental specification of programs, (2) comparing different specifications for the same program, and (3) obtaining information for specification generation tools. Our approach has been implemented as a prototype for Java which uses the heavyweight symbolic execution system KeY as a backend. We studied its practicability with several small examples and plan to conduct a more extensive case study in the near future
    corecore